#include "StdAfx.h"
#include "hater.h"

#include <winsock2.h>
#pragma comment(lib, "ws2_32")
#include <windows.h>

#include "internal/md5.h"
#include "internal/UTFCoding.h"

namespace Zen{namespace utility{

StringList StringSplit(const string& strText, char cDelim)
{
	StringList ret;
	ret.clear();
	istringstream ss(strText);
	string strTemp;
	while (getline(ss, strTemp, cDelim))
	{
		if (!strTemp.empty())
			ret.push_back(strTemp);
	}
	return ret;
}

string StringJoin(const StringList& sg, char cDelim)
{
	string ret;
	for (StringList::const_iterator i = sg.begin(); i != sg.end(); ++i)
	{
		if (!i->empty())
		{
			if (i != sg.begin())
				ret.push_back(cDelim);
			ret += *i;
		}
	}
	return ret;
}

string StringFormat(int nSize, const char* szFormat, ...)
{
	va_list ap;
	char* pBuf = reinterpret_cast<char*>(_malloca(nSize));
	va_start(ap, szFormat);
	vsprintf(pBuf, szFormat, ap);
	va_end(ap);
	string ret(pBuf);
	_freea(pBuf);
	return ret;
}

wstring StringFormat(int nSize, const wchar_t* szFormat, ...)
{
	va_list ap;
	//wchar_t* pBuf = reinterpret_cast<wchar_t*>(_malloca(nSize));
	wchar_t* pBuf = new wchar_t[nSize];
	va_start(ap, szFormat);
	vswprintf(pBuf, szFormat, ap);
	va_end(ap);
	wstring ret(pBuf);
	//_freea(pBuf);
	delete []pBuf;
	return ret;
}

string WrapText(const string& strText, char cWrapper)
{
	string ret(1, cWrapper);
	ret += strText;
	ret.push_back(cWrapper);
	return ret;
}

string _FormatCurTime(const char* szFormat)
{
	time_t t = time(0);
	char szBuf[50] = {0};
	strftime(szBuf, sizeof(szBuf), szFormat, localtime(&t));
	return string(szBuf);
}

string GetCurDateTime()
{
	return _FormatCurTime("%Y-%m-%d %H:%M:%S");
}

string GetCurDate()
{
	return _FormatCurTime("%Y-%m-%d");
}

string GetCurTime()
{
	return _FormatCurTime("%H:%M:%S");
}

string GetLocalIP()
{
	string strIP;
	char szHostName[MAX_PATH] = {0};
	gethostname(szHostName, sizeof(szHostName));
	if (hostent* pHost = gethostbyname(szHostName))
		strIP.assign(inet_ntoa(*reinterpret_cast<in_addr*>(pHost->h_addr)));
	return strIP;
}


string GetMD5(istream& is)
{
	md5_byte_t hash[64] = {0};
	md5_state_t state;
	md5_init(&state);
	char buf[2048] = {0};
	while (is)
		md5_append(&state, (const md5_byte_t*)buf, is.read(buf, sizeof(buf)).gcount());
	md5_finish(&state, hash);
	char szResult[128] = {0};
	TranslateMd5ToString(hash, szResult);
	return string(szResult);
}

string IConv(const string& strText, IConvType from, IConvType to)
{
	if (from == to)
		return strText;

	CUTFCoding enc;
	unsigned char* pText = const_cast<unsigned char*>(
		reinterpret_cast<const unsigned char*>(strText.c_str()));

	if (to == kUTF16)
		enc.MutiByToUnicode(pText, (from == kLocal) ? CP_ACP : CP_UTF8);
	else if (from == kUTF16)
		enc.UnicodeToMutiBy(reinterpret_cast<WCHAR*>(pText), (to == kLocal) ? CP_ACP : CP_UTF8);
	else if (from == kUTF8 && to == kLocal)
		enc.UTF8ToMutiBy(pText);
	else if (from == kLocal && to == kUTF8)
		enc.MutiByToUTF8(pText);
	else
		return string();

	if (to == kUTF16)
	{
		WCHAR* pWRet = NULL;
		long nLen = 0;
		enc.GetText(pWRet, nLen);
		nLen -= 1;
		nLen *= (sizeof(WCHAR)/sizeof(char));
		return string(reinterpret_cast<const char*>(pWRet), nLen);
	}
	else
	{
		unsigned char* pRet = NULL;
		unsigned long nLen = 0;
		enc.GetText(pRet, nLen);
		nLen -= 1;
		return string(reinterpret_cast<const char*>(pRet), nLen);
	}
}

wstring a2w(const string& a)
{
	return wstring(reinterpret_cast<const WCHAR*>(a.c_str()), 
		a.size() /(sizeof(WCHAR)/sizeof(char)));
}

string w2a(const wstring& w)
{
	return string(reinterpret_cast<const char*>(w.c_str()),
		w.size() * (sizeof(WCHAR)/sizeof(char)));
}

int a2i(const string& a)
{
	return atoi(a.c_str());
}

string i2a(int i)
{
	char szBuf[64] = {0};
	itoa(i, szBuf, 10);
	return string(szBuf);
}

//static streambuf rbuf;


}}//end utility//end Zen
